package com.wobuhekele.core;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.RandomAccessFile;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.wobuhekele.domain.DownResultBean;
import com.wobuhekele.util.StreamUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


/**
 * 类AbstractDownExecute.java的实现描述：操作核心类
 * 
 * @author chenrs 2015年12月7日 下午11:24:23
 */
public abstract class AbstractDownExecute extends AbstractHttpConnection {
	
	Logger logger = LoggerFactory.getLogger(AbstractDownExecute.class);
	public static int threadSize = 5;
	
	ExecutorService executor = Executors.newFixedThreadPool(this.threadSize);
	
	/**
	 * @param url
	 */
	public AbstractDownExecute(String url,int threadSize) {
		super(url,threadSize);
		this.threadSize = threadSize;
		
	}
	
	
	
	/**
	 * @return the executor
	 */
	public ExecutorService getExecutor() {
		return executor;
	}



	/** 
	 * 用于下载文件
	 * @Author xchen
	 * @Date 2017-3-27 - 上午10:34:01
	 */
	protected  void down(InputStream inputStream) {
		int length = getContentLength();
		int singleThreadExecuteSize = (length % threadSize) > 0 ? length / threadSize +1 : length / threadSize;
		
	}
	
	/**
	 *  返回每个线程的临时文件
	 *@param quotoTasks
	 *@return
	 * @throws ExecutionException 
	 * @throws InterruptedException 
	 * @Author xchen
	 * @Date 2017-3-27 - 上午11:11:17
	 */
	protected  List<Future<DownResultBean>> deployTask(List<Future<DownResultBean>> invokeAll) throws Exception{
		logger.debug("返回每个线程的临时文件步骤开始------");
		List<Future<DownResultBean>> tempResultList = new ArrayList<Future<DownResultBean>>();
		//将所有的临时文件LIst  解析成数组  写入到目标文件中
		
		for(int i=0;i<invokeAll.size(); i++){
			// 得到当前线程的临时文件 
			final DownResultBean downResultBean = invokeAll.get(i).get(); 
			final List<File> localTempFiles = downResultBean.getLocalTempFiles();
			if(localTempFiles != null  && localTempFiles .size()>0){
				// 目前只有每个线程一个临时文件
//				File tempFile = localTempFiles.get(0);
				//将临时文件转成数组
				Future<DownResultBean> submit = executor.submit(new Callable<DownResultBean>() {
					
				@Override
				public DownResultBean call() throws Exception {
					// TODO Auto-generated method stub
					byte [] localReturnCache = new byte[]{};
					for(int j=0 ; j<localTempFiles.size(); j++){
						File file = localTempFiles.get(j);
						System.out
								.println("file  "+j+"文件的大小为"+ file.length());
						FileInputStream fis = new FileInputStream(file);
						byte [] cache = new byte[1024];
						int b;
						while((b=fis.read(cache, 0 ,cache.length)) != -1){
							localReturnCache = StreamUtils.addBufferByte(cache, 0, b, localReturnCache);
						}
						fis.close();
						file.delete();
					}
//														resultByte = ArrayUtils.addAll(resultByte, localReturnCache);
					DownResultBean downResultBean2 = new DownResultBean();
					// 临时文件只有一个 只需要记录 它是那个线程的临时文件 用于最后的组装即可
					downResultBean2.setLocal(downResultBean.getLocal()); // 
					downResultBean2.setTempByte(localReturnCache);
					downResultBean2.setStartIndex(downResultBean.getStartIndex());
					localReturnCache = null;
					return downResultBean2;
				}
			});
//				submit.get();
				tempResultList.add(submit);
			}
		}
		logger.debug("返回每个线程的临时文件步骤结束------");
		return tempResultList;
	}
	
	
	/**
	 *  将线程中的temp文件直接写入到目标文件中
	 *@param tempResultList
	 *@param singleThreadExecuteSize
	 *@throws InterruptedException
	 *@throws ExecutionException
	 * @Author xchen
	 * @Date 2017-3-27 - 上午11:23:16
	 */
	protected void TempFileTranslateByte(List<Future<DownResultBean>> tempResultList,int singleThreadExecuteSize,final String resultPath) throws InterruptedException, ExecutionException{
		logger.debug("将线程中的temp文件直接写入到目标文件中----- 开始");
		for(int j =0 ;j<tempResultList.size();  j++){
			Future<DownResultBean> future = tempResultList.get(j);
			final DownResultBean downResultBean2 = future.get();
		    byte[] tempByte1 = future.get().getTempByte();
		    final byte []  tempByte = tempByte1;
			int skipTemp = 0;
			if(downResultBean2.getLocal() == (threadSize -1)){//最后一个
				skipTemp = getContentLength() - singleThreadExecuteSize +1; 
			}else if (downResultBean2.getLocal() != (threadSize -1)){//非最后一个
				skipTemp = downResultBean2.getLocal()* singleThreadExecuteSize;
			}
			System.out.println("当前跳过的距离skip " +skipTemp + skipTemp/singleThreadExecuteSize +"  local "+ downResultBean2.getLocal());
			final int skip = downResultBean2.getStartIndex();
			
			executor.submit(new Callable<String>() {

				@Override
				public String call() throws Exception {
					File resultFile = new File(resultPath);
					RandomAccessFile accessFile = new RandomAccessFile(resultFile, "rw");
//					System.out.println("跳过的距离 skip " );
					accessFile.seek(skip);
					accessFile.write(tempByte,0,tempByte.length);
					System.out.println("tempByte 的大小 == " + tempByte.length + "文件的大小为  "+accessFile.length()  + "跳过的大小skip   " + skip +"  local "+ downResultBean2.getLocal());
					accessFile.close();
					return null;
				}
			}) ;
		}
		logger.debug("将线程中的temp文件直接写入到目标文件中----- 结束");
	}
}
